/*
 * @(#)DefaultAction.java	1.0 Apr 27, 2008
 *
 *	The MIT License
 *
 *	Copyright (c) 2008 Malachi de AElfweald <malachid@gmail.com>
 *
 *	Permission is hereby granted, free of charge, to any person obtaining a copy
 *	of this software and associated documentation files (the "Software"), to deal
 *	in the Software without restriction, including without limitation the rights
 *	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *	copies of the Software, and to permit persons to whom the Software is
 *	furnished to do so, subject to the following conditions:
 *
 *	The above copyright notice and this permission notice shall be included in
 *	all copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *	THE SOFTWARE.
 */
package org.eoti.swing;

import org.eoti.swing.text.Mnemonic;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.net.URL;

public class DefaultAction
extends AbstractAction
{
	protected static String ACTION_MNEMONIC = "Mnemonic";
	protected EventListenerList listeners;

	public DefaultAction()
	{
		super();
	}

	public DefaultAction(String name)
	{
		this();
		setName(name);
	}

	public DefaultAction(String name, Icon icon)
	{
		this();
		setName(name);
		setSmallIcon(icon);
	}

	public void actionPerformed(ActionEvent event)
	{
		if(listeners == null) return;
		ActionEvent newEvent = new ActionEvent(
			event.getSource(),
			event.getID(),
			getActionCommand()
		);

		for(ActionListener listener : listeners.getListeners(ActionListener.class))
			listener.actionPerformed(newEvent);
	}

	public DefaultAction withActionCommand(String actionCommand)
	{
		setActionCommand(actionCommand);
		return this;
	}

	public void setActionCommand(String actionCommand)
	{
		putValue(Action.ACTION_COMMAND_KEY, actionCommand);
	}

	public String getActionCommand()
	{
		return (String) getValue(Action.ACTION_COMMAND_KEY);
	}

	public DefaultAction withName(String name)
	{
		setName(name);
		return this;
	}

	public void setName(String name)
	{
		putValue(Action.NAME, name);
	}

	public DefaultAction withMnemonic(Mnemonic mnemonic)
	{
		setMnemonic(mnemonic);
		return this;
	}

	public void setMnemonic(Mnemonic mnemonic)
	{
		if(mnemonic == null)
		{
			putValue(Action.NAME, null);
			putValue(Action.MNEMONIC_KEY, Mnemonic.DEFAULT_CHAR);
			putValue(ACTION_MNEMONIC, null);
			putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, Mnemonic.DEFAULT_LOC);
			return;
		}

		putValue(Action.NAME, mnemonic.getName());
		char key = mnemonic.getCharacter();
		if(key != Mnemonic.DEFAULT_CHAR)
			putValue(Action.MNEMONIC_KEY, new Integer(key));

		putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, mnemonic.getIndex());

		putValue(ACTION_MNEMONIC, mnemonic);
	}

	public String getName()
	{
		return (String) getValue(Action.NAME);
	}

	public Mnemonic getMnemonic()
	{
		return (Mnemonic) getValue(ACTION_MNEMONIC);
	}

	public Integer getMnemonicChar()
	{
		return (Integer) getValue(Action.MNEMONIC_KEY);
	}

	public DefaultAction withShortDescription(String desc)
	{
		setShortDescription(desc);
		return this;
	}

	public void setShortDescription(String desc)
	{
		putValue(Action.SHORT_DESCRIPTION, desc);
	}

	public String getShortDescription()
	{
		return (String) getValue(Action.SHORT_DESCRIPTION);
	}

	public DefaultAction withLongDescription(String desc)
	{
		setLongDescription(desc);
		return this;
	}

	public void setLongDescription(String desc)
	{
		putValue(Action.LONG_DESCRIPTION, desc);
	}

	public String getLongDescription()
	{
		return (String) getValue(Action.LONG_DESCRIPTION);
	}

	public DefaultAction withSmallIcon(Icon icon)
	{
		setSmallIcon(icon);
		return this;
	}

	public void setSmallIcon(Icon icon)
	{
		putValue(Action.SMALL_ICON, icon);
	}

	public Icon getSmallIcon()
	{
		return (Icon) getValue(Action.SMALL_ICON);
	}

	public DefaultAction withSmallIcon(String resourcePath)
	{
		setSmallIcon(resourcePath);
		return this;
	}

	public void setSmallIcon(String resourcePath)
	{
		if(resourcePath == null) return;
		URL url = getClass().getResource(resourcePath);
		if(url == null) return;
		setSmallIcon(new ImageIcon(url));
	}

	public DefaultAction withLargeIcon(Icon icon)
	{
		setLargeIcon(icon);
		return this;
	}

	public void setLargeIcon(Icon icon)
	{
		putValue(Action.LARGE_ICON_KEY, icon);
	}

	public Icon getLargeIcon()
	{
		return (Icon) getValue(Action.LARGE_ICON_KEY);
	}

	public DefaultAction withLargeIcon(String resourcePath)
	{
		setLargeIcon(resourcePath);
		return this;
	}

	public void setLargeIcon(String resourcePath)
	{
		if(resourcePath == null) return;
		URL url = getClass().getResource(resourcePath);
		if(url == null) return;
		setLargeIcon(new ImageIcon(url));
	}

	public DefaultAction withAccelerator(KeyStroke keyStroke)
	{
		setAccelerator(keyStroke);
		return this;
	}

	public void setAccelerator(KeyStroke keyStroke)
	{
		putValue(Action.ACCELERATOR_KEY, keyStroke);
	}

	public KeyStroke getAccelerator()
	{
		return (KeyStroke) getValue(Action.ACCELERATOR_KEY);
	}

	public DefaultAction withAccelerator(String keyStroke)
	{
		setAccelerator(keyStroke);
		return this;
	}

	public void setAccelerator(String keyStroke)
	{
		KeyStroke ks = KeyStroke.getKeyStroke(keyStroke);
		if(ks == null) return;
		setAccelerator(ks);
	}

	public void addActionListener(ActionListener listener)
	{
		if(listener == null) return;
		if(listeners == null) listeners = new EventListenerList();
		listeners.add(ActionListener.class, listener);
	}

	public void removeActionListener(ActionListener listener)
	{
		if(listener == null) return;
		if(listeners == null) return;
		listeners.remove(ActionListener.class, listener);
//		if(listeners.getListenerCount(ActionListener.class) == 0)
//			listeners = null;
	}

	public DefaultAction copy()
	{
		DefaultAction action = new DefaultAction();
		action.setMnemonic(getMnemonic());
		// setMnemonic takes care of setName too
//		action.setName(getName());
		action.setActionCommand(getActionCommand());
		action.setShortDescription(getShortDescription());
		action.setLongDescription(getLongDescription());
		action.setSmallIcon(getSmallIcon());
		action.setLargeIcon(getLargeIcon());
		action.setAccelerator(getAccelerator());


		for(ActionListener listener : listeners.getListeners(ActionListener.class))
			action.addActionListener(listener);

		return action;
	}
}
